package model;

import java.util.ArrayList;
import java.util.List;

/**
 * Une {@link Balise} représente la structure du {@link Document}
 * et contient des {@link Mot}s.
 */
public class Balise
{
  /** The id of the balise in the database. */
  private int id;
  
  /** The nom. */
  private String nom;
  
  /** The chemin. */
  private String chemin;
  
  /** The doc. */
  private Document doc;
  
  /** The mots. */
  private List<Mot> mots;

  /** The id of the balise in the parent. */
  private int baliseId;

  /**
   * Instantiates a new balise.
   *
   * @param nom the nom
   * @param chemin the chemin
   * @param document the document
   * @param baliseId the balise id
   */
  public Balise(String nom, String chemin, Document document, int baliseId)
  {
    this(-1, nom, chemin, document, new ArrayList<Mot>(), baliseId);
  }
  
  /**
   * Instantiates a new balise.
   *
   * @param id the id
   * @param nom the nom
   * @param chemin the chemin
   * @param doc the doc
   * @param mots the mots
   * @param baliseId the balise id
   */
  public Balise(int id, String nom, String chemin, Document doc, List<Mot> mots, int baliseId)
  {
    this.id = id;
    this.nom = nom;
    this.chemin = chemin;
    this.doc = doc;
    this.mots = mots;
    this.baliseId = baliseId;
  }

  /**
   * Gets the id.
   *
   * @return the id
   */
  public int getId()
  {
    return id;
  }
  
  /**
   * Gets the unique id of the balise.
   *
   * @return the unique id
   */
  public String getUniqueID()
  {
    return chemin + nom + baliseId + doc.getId();
  }

  /**
   * Gets the nom.
   *
   * @return the nom
   */
  public String getNom()
  {
    return nom;
  }

  /**
   * Gets the chemin.
   *
   * @return the chemin
   */
  public String getChemin()
  {
    return chemin;
  }

  /**
   * Gets the doc.
   *
   * @return the doc
   */
  public Document getDocument()
  {
    return doc;
  }

  /**
   * Gets the list terme.
   *
   * @return the list terme
   */
  public List<Mot> getMots()
  {
    return mots;
  }
  
  /**
   * Ajoute un mot à la liste de mots de cette balise.
   *
   * @param mot le mot à ajouter
   */
  public void ajouterMot(Mot mot)
  {
    mots.add(mot);
  }

  /**
   * Gets the id of the balise in the parent.
   *
   * @return the balise id
   */
  public int getBaliseNumber()
  {
    return baliseId;
  }

  /**
   * Merge this object with a given balise.<br>
   * If a value of the given balise is not null, it will
   * replace the value of the current balise. Otherwise,
   * it's the content of the current balise that will be taken
   *
   * @param balise the balise
   * @return a new instance of balise
   */
  public Balise merge(Balise balise)
  {
    int id = balise.getId() != -1 ? balise.getId() : this.id;
    String nom = balise.getNom() != null ? balise.getNom().equals("") ? this.nom : balise.getNom() : this.nom;
    String chemin = balise.getChemin() != null ? balise.getChemin().equals("") ? this.chemin : balise.getChemin() : this.chemin;
    Document doc = balise.getDocument() != null ? balise.getDocument() : this.doc;
    List<Mot> mots = balise.getMots() != null ? balise.getMots() : this.mots;
    int baliseId = balise.getBaliseNumber() != -1 ? balise.getBaliseNumber() : this.baliseId;
    return new Balise(id, nom, chemin, doc, mots, baliseId);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(Object obj)
  {
    boolean equals = false;
    if (obj instanceof Balise)
    {
      Balise balise = (Balise) obj;
      equals = balise.getUniqueID().equals(getUniqueID());
    }
    return equals;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return 24 * getUniqueID().hashCode();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return this.nom;
  }
}
